#!/usr/bin/perl
#
# Copyright (c) 2020 NVI, Inc.
#
# This file is part of VLBI Field System
# (see http://github.com/nvi-inc/fs).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

# 1.0 Initialize

use PGPLOT;
require "getopts.pl";

&Getopts("vhc:f:piu:l:");

if ($#ARGV < 0 &&!defined($opt_h) &&!defined($opt_v)) {
    print STDERR "Try: 'pcalamp -h'\n";
    exit -1;
}

if(defined($opt_v)) {
    print "[pcalamp 1.2]\n";
    pgqinf("VERSION",$val,$len);
    print "using PGPLOT module version $PGPLOT::VERSION, PGPLOT $val library\n";
    exit -1;
}

if (defined($opt_h)) {
    print "Usage: pcalamp  -c string -vhpi -u upper -l lower -f file/device logs\n";
    print "Synopsis: extracts and plots pcal amplitudes from log files\n\n";

    print "This script processes log files to produce plots of pcal amplitudes. The\n";
    print "default is pcal amplitudes for the first set of amplitudes that appear in the\n";
    print "file. This behavior can be modified with the '-c' option to plot the first\n";
    print "occurrence of amplitude data after a FS command that contains the specified\n";
    print "string.\n\n";

    print "Option explanations:\n";
    print " -c string plot first set of amplitudes found after a command/procedure\n";
    print "    matching 'string' was recorded in the log, for this to work; the\n";
    print "    command/procedure matching 'string' must not be called from a procedure,\n";
    print "    unless the procedure is logged with 'xlog=on'\n";
    print " -p plot using power units for comparison to autocorrelation plots\n";
    print " -i autoscale each plot individually\n";
    print " -l lower  eliminate points smaller than lower when auto-scaling plots\n";
    print " -u upper  eliminate points larger  than upper when auto-scaling plots\n";
    print " -v print program and PGPLOT version information and stop\n";
    print " -h print this help information and stop\n";
    print " -f file/device  send graphs to 'file' using PGPLOT 'device'\n";
    print "    if -f omitted and DISPLAY is defined, an xterm will be used\n";
    print "    if -f omitted and DISPLAY is not defined, 'pcalamp.ps/vps' will be used\n";
    print "    if '-f ?', you will be prompted for standard pgplot devices,\n";
    print "                be sure to quote '?', like \\?\n";
    print "    'vps' (portrait PostScript) is a useful choice for 'device' for file output\n";
    exit -1;
}

if(defined($ENV{'DISPLAY'}) && !defined($opt_f)) {
    $dev="/xterm";
} elsif(!defined($opt_f)) {
    $dev="pcalamp.ps/vps";
} else {
    $dev=$opt_f;
}

# 2.0 extract data

for ($i=0;$i<17;$i++) {
    $count[0][$i]=0;
    $count[1][$i]=0;
}
$some=0;
$first=1;
foreach $file (@ARGV) {
    if(!defined($save_file)) {
	$save_file=$file;
    }
    open(FILE,$file) || do {
	print STDERR "can't open $file: $!\n";
	next;
    };
#   print "file $file \n";
    $x=0;
    $y=0;
    while (<FILE>) {
	if(/;location,([^,]*)/i) {
	    $location=$1;
	}
	
	if(defined($opt_c)&&!$found) {
	    next if(!/^.{20}[^&].*$opt_c/);
#	    print "found '$_'\n";
	    $found=1;
	}
		
	if(/pcalports=([^,]*),([0-9]+)/i||/vsi4=[^,]*,([^,]*),([0-9]+)/i) {
	    $x=$1;
	    $y=$2;
#	    print "Pcalports $x, $y \n";
	    if($first || $count[0][$x]!=0 || $count[1][$x]!=0
	       || $count[0][$y]!=0 || $count[1][$y]!=0 ) {
#		print "end\n";
		if(!$first) {
		    print "Detected a repeated measurement,";
		    print " plotting what I had before and then quiting.\n";
		    goto PLOT;
		}
                $first=0;
		$date=substr($_,0,17);
	    }
	} elsif (/decode4\/[p]*cal ([lu])sb([xy])/i) {
	    $sb = $1;
	    if($sb eq "u") {
		$band=1;
	    } elsif($sb eq "l") {
		$band=0;
	    } else {
		die "unknown side-band $sb\n";
	    }
	    $port=$2;
	    if($port eq "x") {
		$chan=$x;
	    } elsif ($port eq "y") {
		$chan=$y;
	    } else {
		die "unknown pcal port $port\n";
	    }
	    ($time,$type,@fields)=split(' ');
	    while($freq=shift(@fields)) {
		$freq=$freq/1e6;
		$amp=shift(@fields);
		$phase=shift(@fields);
#		print "$chan $band $port $freq $amp $phase\n";
		$frequencies[$band][$chan][$count[$band][$chan]]=$freq;
		$value=$amp;
#if power, convert to fractional, square, convert to output units
		$value=$amp*.001*$amp*.001*10000. if defined($opt_p);
		$amplitudes[$band][$chan][$count[$band][$chan]]=$value;
		$count[$band][$chan]++;
		$some=1;
	    }
	}
    }
}

# 3.0 Find max value

PLOT:
die "no data to plot\n" if !$some;

$maxv=-1;
$minv=1e6;
for($i=1;$i<15;$i++) {
    for($j=0;$j<2;$j++) {
	$imaxv[$j][$i]=-1;
	$iminv[$j][$i]=1e6;
	for($k=0;$k<$count[$j][$i];$k++) {
	    next if defined($opt_u) && $amplitudes[$j][$i][$k] > $opt_u;
	    next if defined($opt_l) && $amplitudes[$j][$i][$k] < $opt_l;
	    if($amplitudes[$j][$i][$k]>$imaxv[$j][$i]) {
		$imaxv[$j][$i]=$amplitudes[$j][$i][$k];
	    }
	    if($amplitudes[$j][$i][$k]<$iminv[$j][$i]) {
		$iminv[$j][$i]=$amplitudes[$j][$i][$k];
	    }
	    if($amplitudes[$j][$i][$k]>$maxv) {
		$maxv=$amplitudes[$j][$i][$k];
	    }
	    if($amplitudes[$j][$i][$k]<$minv) {
		$minv=$amplitudes[$j][$i][$k];
	    }
	}
    }
}
for($i=1;$i<15;$i++) {
    for($j=0;$j<2;$j++) {
	if(!defined($opt_i)) {
	    $imaxv[$j][$i]=$maxv;
	    $iminv[$j][$i]=$minv;
	}	
	$imaxv[$j][$i]=9.99 if $imaxv[$j][$i] < 10;
	$upper[$j][$i]=10 * (1+int $imaxv[$j][$i]/10);
	$lower[$j][$i]=10 * (int $iminv[$j][$i]/10);
	$ticks[$j][$i]=($upper[$j][$i]-$lower[$j][$i])/2;
	$upper[$j][$i]=$upper[$j][$i]-0.01;
#	print " Upper $upper[$j][$i] Lower $lower[$j][$i] ticks $ticks[$j][$i]\n";
    }
}

# 4.0 plot

pgbegin(0,$dev,2,16);
pgsch(10);

for($i=1;$i<15;$i++) {
#    print " Plot loop $i\n";
    for($j=0;$j<2;$j++) {
	pgpanl(1+$j,1+$i);
	pgvport(0.15,.95,0,1);
	pgwindow(-0.5,16.5,$lower[$j][$i],$upper[$j][$i]);
	if($i != 14) {
	    pgbox("BCST",0.0,0,"BCNST",$ticks[$j][$i],2);
	} else {
	    pgbox("BCNST",0.0,0,"BCNST",$ticks[$j][$i],2);
	    pglabel("Baseband Frequency (MHz)","","");
	}
	
	if($j == 0) {
	    pglabel("","L$i","");
	} else {
	    pglabel("","U$i","");
	}
	for($k=0;$k<$count[$j][$i];$k++) {
	    $fr[$k]=$frequencies[$j][$i][$k];
	    $am[$k]=$amplitudes[$j][$i][$k];
#		print "U$i $j $fr[$j] $am[$j]\n";
	}
	pgpoint($count[$j][$i], \@fr,\@am,17);
	pgline($count[$j][$i], \@fr,\@am);
    }
}

pgpanl(1,1);
pgvport(0.15,.95,0,1);
pgwindow(-0.5,16.5,0,39);

$string="";
$string=$opt_c if (defined($opt_c));
if(defined($opt_p)) {
pgtext(3,10,"$location Pcal Amplitude (Power, 0.01%) -- $date $save_file $string");
} else {
pgtext(3,10,"$location Pcal Amplitude (Voltage, 0.1%) -- $date $save_file $string");
}
pgend;
